//
//  FastEnumerationAndSynthesisTest.m
//  test_simple_project
//
//  快速枚举和属性合成指令测试实现 - 修复版本
//

#import "FastEnumerationAndSynthesisTest.h"
#import <objc/runtime.h>

@interface FastEnumerationAndSynthesisTest ()
@property (strong, nonatomic) NSString *customBackingVar;  // 修复: 移除下划线前缀
@end

@implementation FastEnumerationAndSynthesisTest

// 属性合成指令测试
@synthesize synthesizedProperty = _synthesizedProperty;  // 修复: 明确指定backing变量
@synthesize customBackingProperty = _customBackingProperty;
@synthesize readOnlyProperty = _readOnlyProperty;
@synthesize customBackedProperty = _customBackedProperty;  // 修复: 使用不同的backing变量名

// 动态属性声明
@dynamic dynamicProperty;

- (instancetype)init {
    self = [super init];
    if (self) {
        _synthesizedProperty = @"Synthesized Property";
        _customBackingProperty = [[NSMutableArray alloc] init];
        _readOnlyProperty = @"Read Only Property";
        _customBackedProperty = @"Custom Backed Property";  // 修复: 使用正确的变量名
    }
    return self;
}

#pragma mark - Fast Enumeration Testing Methods

- (void)testBasicFastEnumeration {
    NSArray *testArray = @[@"Apple", @"Banana", @"Cherry", @"Date", @"Elderberry"];
    
    NSLog(@"=== Basic Fast Enumeration Test ===");
    for (NSString *fruit in testArray) {
        NSLog(@"Fruit: %@", fruit);
    }
}

- (void)testNestedFastEnumeration {
    NSArray *categories = @[
        @[@"Apple", @"Banana", @"Cherry"],
        @[@"Carrot", @"Broccoli", @"Spinach"],
        @[@"Chicken", @"Beef", @"Fish"]
    ];
    
    NSLog(@"=== Nested Fast Enumeration Test ===");
    for (NSArray *category in categories) {
        NSLog(@"Category with %lu items:", (unsigned long)category.count);
        for (NSString *item in category) {
            NSLog(@"  - %@", item);
        }
    }
}

- (void)testFastEnumerationWithFiltering {
    NSArray *numbers = @[@1, @2, @3, @4, @5, @6, @7, @8, @9, @10];
    
    NSLog(@"=== Fast Enumeration with Filtering Test ===");
    NSLog(@"Even numbers:");
    for (NSNumber *number in numbers) {
        if ([number intValue] % 2 == 0) {
            NSLog(@"  %@", number);
        }
    }
    
    NSLog(@"Odd numbers:");
    for (NSNumber *number in numbers) {
        if ([number intValue] % 2 != 0) {
            NSLog(@"  %@", number);
        }
    }
}

- (void)testFastEnumerationBreakAndContinue {
    NSArray *testArray = @[@"Start", @"Continue", @"Skip", @"Break", @"Never Reached"];
    
    NSLog(@"=== Fast Enumeration Break and Continue Test ===");
    for (NSString *item in testArray) {
        if ([item isEqualToString:@"Skip"]) {
            NSLog(@"Skipping: %@", item);
            continue;
        }
        
        if ([item isEqualToString:@"Break"]) {
            NSLog(@"Breaking at: %@", item);
            break;
        }
        
        NSLog(@"Processing: %@", item);
    }
}

#pragma mark - Collection Fast Enumeration Tests

- (void)testArrayFastEnumeration {
    NSMutableArray *mutableArray = [@[@"Mutable", @"Array", @"Test"] mutableCopy];
    
    NSLog(@"=== Array Fast Enumeration Test ===");
    NSLog(@"Original array:");
    for (NSString *item in mutableArray) {
        NSLog(@"  %@", item);
    }
    
    // 添加元素
    [mutableArray addObject:@"Added"];
    
    NSLog(@"After adding element:");
    for (NSString *item in mutableArray) {
        NSLog(@"  %@", item);
    }
}

- (void)testDictionaryFastEnumeration {
    NSDictionary *testDictionary = @{
        @"name": @"John Doe",
        @"age": @30,
        @"city": @"New York",
        @"occupation": @"Developer"
    };
    
    NSLog(@"=== Dictionary Fast Enumeration Test ===");
    NSLog(@"Dictionary keys:");
    for (NSString *key in testDictionary) {
        NSLog(@"  %@: %@", key, testDictionary[key]);
    }
    
    NSLog(@"Dictionary key-value pairs using allKeys:");
    for (NSString *key in [testDictionary allKeys]) {
        NSLog(@"  %@ = %@", key, testDictionary[key]);
    }
}

- (void)testSetFastEnumeration {
    NSSet *testSet = [NSSet setWithObjects:@"Unique", @"Set", @"Elements", @"No", @"Duplicates", nil];
    
    NSLog(@"=== Set Fast Enumeration Test ===");
    NSLog(@"Set elements (order may vary):");
    for (NSString *element in testSet) {
        NSLog(@"  %@", element);
    }
    
    NSMutableSet *mutableSet = [testSet mutableCopy];
    [mutableSet addObject:@"Added Element"];
    
    NSLog(@"Mutable set after adding element:");
    for (NSString *element in mutableSet) {
        NSLog(@"  %@", element);
    }
}

- (void)testCustomCollectionEnumeration {
    CustomEnumerableCollection *customCollection = [[CustomEnumerableCollection alloc] 
                                                    initWithObjects:@[@"Custom", @"Collection", @"Test"]];
    
    [customCollection addObject:@"Added"];
    
    NSLog(@"=== Custom Collection Fast Enumeration Test ===");
    NSLog(@"Custom collection elements:");
    for (NSString *item in customCollection) {
        NSLog(@"  %@", item);
    }
    
    NSLog(@"Collection count: %lu", (unsigned long)[customCollection count]);
}

#pragma mark - Property Synthesis Testing Methods

- (void)testPropertySynthesis {
    NSLog(@"=== Property Synthesis Test ===");
    
    // 测试合成属性
    self.synthesizedProperty = @"New Synthesized Value";
    NSLog(@"Synthesized property: %@", self.synthesizedProperty);
    
    // 测试自定义backing变量
    [self.customBackingProperty addObject:@"Item 1"];
    [self.customBackingProperty addObject:@"Item 2"];
    NSLog(@"Custom backing property: %@", self.customBackingProperty);
    
    // 测试只读属性
    NSLog(@"Read-only property: %@", self.readOnlyProperty);
}

- (void)testCustomBackingVariable {
    NSLog(@"=== Custom Backing Variable Test ===");
    
    // 测试自定义backing变量的属性
    self.customBackedProperty = @"Custom Backed Value";
    NSLog(@"Custom backed property: %@", self.customBackedProperty);
    
    // 直接访问backing变量
    _customBackedProperty = @"Direct custom backing var access";  // 修复: 使用正确的变量名
    NSLog(@"Direct backing variable access: %@", self.customBackedProperty);
}

- (void)testDynamicProperties {
    NSLog(@"=== Dynamic Properties Test ===");
    
    // 动态属性需要手动实现getter和setter
    self.dynamicProperty = @42;
    NSLog(@"Dynamic property: %@", self.dynamicProperty);
}

// 动态属性的手动实现
- (NSNumber *)dynamicProperty {
    return objc_getAssociatedObject(self, @selector(dynamicProperty));
}

- (void)setDynamicProperty:(NSNumber *)dynamicProperty {
    objc_setAssociatedObject(self, @selector(dynamicProperty), dynamicProperty, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

@end

#pragma mark - CustomEnumerableCollection Implementation

@implementation CustomEnumerableCollection

- (instancetype)initWithObjects:(NSArray *)objects {
    self = [super init];
    if (self) {
        _internalArray = [objects mutableCopy];
    }
    return self;
}

- (void)addObject:(id)object {
    [self.internalArray addObject:object];
}

- (NSUInteger)count {
    return self.internalArray.count;
}

// NSFastEnumeration协议实现
- (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state 
                                  objects:(id __unsafe_unretained [])buffer 
                                    count:(NSUInteger)len {
    
    if (state->state == 0) {
        // 第一次调用，初始化状态
        state->state = 1;
        state->mutationsPtr = &state->extra[0];
    }
    
    NSUInteger count = 0;
    unsigned long currentIndex = state->state - 1;
    
    while (currentIndex < self.internalArray.count && count < len) {
        buffer[count] = self.internalArray[currentIndex];
        currentIndex++;
        count++;
    }
    
    state->state = currentIndex + 1;
    state->itemsPtr = buffer;
    
    return count;
}

@end
